package com.code.google.geogallery;

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

import com.drew.imaging.ImageMetadataReader;
import com.drew.lang.GeoLocation;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.GpsDirectory;

public class Generator {

    public static final String TEMPLATE_FILE_NAME = "template.vm";
    
    /**
     * Counts how many images in the selected directory
     * 
     * @param directory
     * @return
     */
    public static int getImagesCount(File directory) {
        return Generator.getImages(directory).size();
    }
    
    private static boolean isImage(String image_path){
        Image image = new ImageIcon(image_path).getImage();
        return (image.getWidth(null) != -1);
    }
    
    /**
     * Scans the directory and returns the only image list
     * 
     * @param directory
     * @return image file list
     */
    private static List<File> getImages(File directory) {
        File[] lstFiles = directory.listFiles();
        List<File> lstImageFiles = new ArrayList<File>();
        for (File file : lstFiles) {

            if (file.isFile() && Generator.isImage(file.getAbsolutePath())) {
                lstImageFiles.add(file);
            }
        }
        return lstImageFiles;
    }
    
    /**
     * Prints all the image data the index.html file.
     * 
     * @param selectedDirectory
     * @return TRUE if success
     * @throws Exception
     */
    public static boolean printHtmlFile(File selectedDirectory, String rootTemplate) {
        List<ImageDTO> listOfImages = null;
        try {
            
            listOfImages = Generator.getListOfImages(selectedDirectory);
        
        } catch (Exception e) {
            return false;
        }
        
        /*  first, get and initialize an engine  */
        VelocityEngine ve = new VelocityEngine();
        Properties props = new Properties();  
        props.put("file.resource.loader.path", rootTemplate);
        ve.init(props);
        
        /*  next, get the Template  */
        Template t = ve.getTemplate(TEMPLATE_FILE_NAME);
        
        /*  create a context and add data */
        VelocityContext context = new VelocityContext();
        context.put("imageList", listOfImages);
        
        /* now render the template into a StringWriter */
        StringWriter writer = new StringWriter();
        t.merge( context, writer );
        
        File outputFile = new File(selectedDirectory + File.separator + "index.html");
        
        if (!outputFile.exists()) {
            try {
                outputFile.createNewFile();
            } catch (IOException e) {
                return false;
            }
        }
        
        try {
            
            PrintWriter out = new PrintWriter(new FileWriter(outputFile));
            out.print(writer.toString());
            out.close();
            
        } catch (IOException e) {
            return false;
        }
        
        return true;
    }
    
    /**
     * Reads all files and analyzes them EXIF data.
     * 
     * @param selectedDirectory
     * @return list of ImageDTO
     * 
     * @throws Exception
     */
    public static List<ImageDTO> getListOfImages(File selectedDirectory) throws Exception {
        List<ImageDTO> lst = new ArrayList<ImageDTO>();
        List<File> imageFiles = Generator.getImages(selectedDirectory);
        
        for (File imgFile : imageFiles) {
            ImageDTO image = new ImageDTO(imgFile.getName());
            
            // read physical width and height
            BufferedImage bufferedImage = ImageIO.read(imgFile);
            image.setHeight(bufferedImage.getHeight());
            image.setWidth(bufferedImage.getWidth());
            
            Metadata metadata = ImageMetadataReader.readMetadata(imgFile);
            GpsDirectory gpsDirectory = metadata.getDirectory(GpsDirectory.class);
            if (gpsDirectory != null) {
                
                // Try to read out the location, making sure it's non-zero
                GeoLocation geoLocation = gpsDirectory.getGeoLocation();
                if (geoLocation != null && !geoLocation.isZero()) {
                    image.setLatitude(geoLocation.getLatitude() + "");
                    image.setLongitude(geoLocation.getLongitude() + "");
                    image.setHasGPS(true);
                }
            }
            
            lst.add(image);
        }
        
        return lst;
    }
}